package com.bmw.order.statemachine;

import com.google.common.base.Supplier;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author: han
 * @since: 2020-12-29 14:17
 **/
public class StateMachine<STATE extends Enum<?>, EVENT extends Enum<?>> {
	// Event事件 --><初始状态，结束状态> 的映射图
	private final LoadingCache<EVENT, Map<STATE, STATE>> transitions =
			CacheBuilder.newBuilder().build(
					CacheLoader.from((Supplier<Map<STATE, STATE>>) () -> new HashMap()));
	// 系统初始状态
	private STATE initialState;
	// 系统潜在的最后状态
	private Set<STATE> finalStates;

	public StateMachine(STATE initState, Set<STATE> finalStates) {
		this.initialState = initState;
		this.finalStates = finalStates;
	}

	/**
	 * 添加状态变化规则
	 */
	public void addTransition(STATE from, STATE to, EVENT e) {
		// 在e对应的event事件内增加新<from, to>状态变化对
		transitions.getUnchecked(e).put(from, to);
	}

	/**
	 * 获取下一状态，根据当前状态和触发event事件
	 */
	public STATE getNextState(STATE from, EVENT e) throws Exception {
		// 获取到下一状态
		STATE target = transitions.getUnchecked(e).get(from);
		if (target == null) {
			throw new Exception();
		}
		return target;
	}
}
